package ijij41.chat;

import java.util.ArrayList;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.Form;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.pubsub.PresenceState;

import ijij41.network.NetworkInformation;
import ijij41.togetherTrain.R;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

public class MultiChatActivity extends Activity {

	private XMPPConnection connection;
	private ArrayList<String> messages = new ArrayList();
	private Handler mHandler = new Handler();
	private ListView mList;
	private EditText mSendText;
	private MultiUserChat muc;
	private MsgMUCListener mMsgListener = new MsgMUCListener();

	private String room_idx;

	public void onCreate(Bundle bundle) {
		super.onCreate(bundle);
		setContentView(R.layout.multichat);

		getParameters();
		initComponent();
		initConnection();

	}

	private void getParameters() {
		// get parameters from before activity
		Intent intent = getIntent();
		room_idx = intent.getStringExtra("room_idx");
		// ///////////////////////
	}

	private void initComponent() {
		mSendText = (EditText) this.findViewById(R.id.sendText);
		Log.i("XMPPClient", "mSendText = " + mSendText);
		mList = (ListView) this.findViewById(R.id.listMessages);
		Log.i("XMPPClient", "mList = " + mList);
		setListAdapter();

		// findViewById(R.id.connect_btn).setOnClickListener(mClickListener);
		findViewById(R.id.btn_back_img).setOnClickListener(mClickListener);
		// Set a listener to send a chat text message
		findViewById(R.id.send).setOnClickListener(mClickListener);

	}

	private void initConnection() {
		try {

			connection();

		} catch (XMPPException e) {
			// Create the room
			e.printStackTrace();
		}
	}

	private Button.OnClickListener mClickListener = new Button.OnClickListener() {
		@Override
		public void onClick(View v) {
			switch (v.getId()) {

			case R.id.btn_back_img:
				if (muc != null)
					muc.leave();
					
				if (connection != null)
					connection.disconnect();

				finish();

				break;

			case R.id.send:
				sendMesseage();
				break;

			default:
				break;
			}

		}

		private void sendMesseage() {

			// TODO thread로 만들어야 한다.
			Log.i("XMPPClient", "send message");

			String text = mSendText.getText().toString();

			/**
			 * Log.i("XMPPClient", "Sending text [" + text + "] to [" + to +
			 * "]"); StringBuffer sb = new StringBuffer(); sb.append(to);
			 * sb.append("@cats-test4.kaist.ac.kr"); Message msg = new
			 * Message(sb.toString(), Message.Type.chat); msg.setBody(text);
			 * connection.sendPacket(msg);
			 **/

			// Message msg = new Message(NetworkInformation.chatRoomName,
			// Message.Type.chat);
			// msg.setBody(text);
			// connection.sendPacket(msg);

			// Create a chat with user2
			Message msg = muc.createMessage();
			msg.setBody(text);
			connection.sendPacket(msg);

			Log.i("XMPPClient", "send message getUser :" + connection.getUser());
			Log.i("XMPPClient", "send message text :" + text);

			// messages.add(connection.getUser() + ":");
			// messages.add(text);

			setListAdapter();

		}
	};

	private void setListAdapter() {
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
				R.layout.multi_line_list_item, messages);
		mList.setAdapter(adapter);
		mList.setSelection(mList.getAdapter().getCount() - 1);
	}

	private void connection() throws XMPPException {

		if (this.connection == null) {

			XMPPConnection conn = tryConnection();

			if (conn != null) {
				setConnection(conn);
				Toast.makeText(MultiChatActivity.this, "Connection Success",
						Toast.LENGTH_SHORT).show();

				if (room_idx == null)
					throw new XMPPException();

				muc = new MultiUserChat(connection, room_idx
						+ NetworkInformation.chatRoomName_postfix);
				muc.addMessageListener(mMsgListener);

				/**if (muc.isJoined()) {
					muc.create("chat" + room_idx);
					Log.i("XMPPClient", "[Settings] Create!!");
				} else { **/
					muc.join("chat" + room_idx);
					Log.i("XMPPClient", "[Settings] Join!!");
				//}

				// Send an empty room configuration form which indicates that we
				// want
				// an instant room
				muc.sendConfigurationForm(new Form(Form.TYPE_SUBMIT));

				Toast.makeText(MultiChatActivity.this,
						"Multi chatting room Success", Toast.LENGTH_SHORT)
						.show();
			} else {
				Log.i("XMPPClient", "[Settings] Unbelieve!!");

			}

		} else {
			Log.i("XMPPClient", "[Settings] Not Happen!!");

			Toast.makeText(MultiChatActivity.this, "Already Connection : ",
					Toast.LENGTH_SHORT).show();
		}

	}

	private class MsgMUCListener implements PacketListener {

		public void processPacket(Packet p) {
			org.jivesoftware.smack.packet.Message message = (org.jivesoftware.smack.packet.Message) p;
			// Message msg = new Message(message);

			if (message.getBody() != null) {
				String fromName = StringUtils.parseBareAddress(message
						.getFrom());
				// String fromName = StringUtils.parseName(message.getFrom());
				Log.i("XMPPClient", "Got text [" + message.getBody()
						+ "] from [" + fromName + "]");
				messages.add(fromName + ":");
				messages.add(message.getBody());
				// Add the incoming message to the list view
				mHandler.post(new Runnable() {
					public void run() {
						setListAdapter();
					}
				});
			}

			// // TODO add que les message pas de type errors
			// ChatMUCAdapter.this.addMessage(msg);
			// final int n = mRemoteListeners.beginBroadcast();
			// for (int i = 0; i < n; i++) {
			// IMessageListener listener = mRemoteListeners
			// .getBroadcastItem(i);
			// try {
			// if (listener != null) {
			// // HL detection
			// // If the pseudo
			// String bodylow = msg.getBody().toLowerCase();
			// if (bodylow.contains(mNick.toLowerCase())) {
			// msg.setHL(true);
			// }
			// // If in the hl list
			// String hls = PreferenceManager
			// .getDefaultSharedPreferences(mService)
			// .getString("settings_key_hls", "");
			// if (!hls.equalsIgnoreCase("")) {
			// for (String hl : hls.split(",")) {
			// if (bodylow.contains(hl.toLowerCase())) {
			// msg.setHL(true);
			// }
			// }
			// }
			// listener.processMUCMessage(ChatMUCAdapter.this, msg);
			// }
			// } catch (RemoteException e) {
			// Log.w(TAG, "Error while diffusing message to listener", e);
			// }
			// }
			// mRemoteListeners.finishBroadcast();

		}

	}

	private void setConnection(XMPPConnection connection) {
		this.connection = connection;
		if (connection != null) {

			// muc.addMessageListener(mMsgListener);

			// // Add a packet listener to get messages sent to us
			// PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
			//
			// connection.addPacketListener(new PacketListener() {
			// public void processPacket(Packet packet) {
			// Message message = (Message) packet;
			// if (message.getBody() != null) {
			// String fromName = StringUtils.parseBareAddress(message
			// .getFrom());
			// Log.i("XMPPClient", "Got text [" + message.getBody()
			// + "] from [" + fromName + "]");
			//
			// messages.add(fromName + ":");
			// messages.add(message.getBody());
			// // Add the incoming message to the list view
			// mHandler.post(new Runnable() {
			// public void run() {
			// setListAdapter();
			// }
			// });
			//
			// }
			// }
			// }, filter);
		}
	}

	private XMPPConnection tryConnection() {

		// Create a connection
		ConnectionConfiguration connConfig = new ConnectionConfiguration(
				NetworkInformation.host,
				Integer.parseInt(NetworkInformation.port),
				NetworkInformation.service);

		XMPPConnection connection = new XMPPConnection(connConfig);

		try {
			if (connection == null)
				Log.i("XMPPClient", "[Setting] null is unreasonable");

			connection.connect();
			Log.i("XMPPClient",
					"[SettingsDialog] Connected to " + connection.getHost());
		} catch (XMPPException e) {
			// TODO: handle exception
			Log.e("XMPPClient",
					"[SettingsDialog] XMPP Connection Failed to connect to "
							+ connection.getHost());
			Log.e("XMPPClient", e.toString());
			return null;
			
		} catch (Exception ex) {
			Log.e("XMPPClient", "[SettingsDialog] Failed to connect to "
					+ connection.getHost());
			Log.e("XMPPClient", ex.toString());
			return null;
			// xmppClient.setConnection(null);
		}

		try {

			connection.login(NetworkInformation.username,
					NetworkInformation.password);
			Log.i("XMPPClient", "Logged in as " + connection.getUser());

			// Set the status to available
			Presence presence = new Presence(Presence.Type.available);
			connection.sendPacket(presence);
			// xmppClient.setConnection(connection);
			return connection;
		} catch (XMPPException ex) {
			Log.e("XMPPClient", "[SettingsDialog] Failed to log in as "
					+ NetworkInformation.username);
			Log.e("XMPPClient", ex.toString());
			// xmppClient.setConnection(null);
			return null;
		}
	}
}
